package model;

/**
 * Created by alex on 11/10/2016.
 */
public abstract class Layer {
    int finIn;
    int finOut;
    double[][]W;
    double[]b;
    double[] delta;
    double[][] deltaW;
    double[] deltab;
    double lr = 0.008;

    public Layer(int finIn, int finOut) {
        this.finIn = finIn;
        this.finOut = finOut;
        this.W = new double[finOut][finIn];
        initW();
        this.b = new double[finOut];
        initB();
        delta= new double[finOut];

        deltaW = new double[finOut][finIn];
        deltab = new double[finOut];
    }
    private void initW() {
        double bound = Math.sqrt(1./(this.finOut+finIn));
        double rand;
        for (int i = 0;i<finOut;i++){
            for(int j = 0;j<finIn;j++){
                rand = 2*(Math.random() -0.5);//-1 ~1
                rand = rand*bound;
                W[i][j] = rand;
                /*
                此处除以10000的效果最好，错误率可以降到0。086以下
                 */
            }
        }
    }

    private void initB(){
        double rand = Math.random();
        for (int i = 0;i<finOut;i++){
            b[i] = rand;
            rand = Math.random();
        }
    }

    public void update(double[][] deltaW, double[] deltab){
        if (deltaW.length!=finOut || deltaW[0].length != finIn){
            System.out.println("deltaW shape error");
        }
        if (deltab.length!=finOut){
            System.out.println("deltab shape error");
        }


        for (int i = 0;i<finOut;i++){
            for (int j = 0;j<finIn;j++){
                W[i][j] -= (lr*deltaW[i][j]);
            }
            b[i]-=(lr*deltab[i]);
        }
    }

    protected double sigmoid(double a){
        return 1.0/(1.0+ Math.exp(-a));
    }

    public abstract double[] output(double[] input);


}
